package com.example.client.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.web.SecurityFilterChain;

import java.util.ArrayList;
import java.util.List;

// 配置 OAuth2 客户端。这包括定义客户端注册信息、登录成功后的处理逻辑
//@Configuration
//@EnableWebSecurity
public class OAuth2ClientSecurityConfig {

//    // 配置 OAuth2 客户端过滤器链, 用于处理 OAuth2 客户端的请求
//    @Bean
//    public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
//        http
//                .authorizeHttpRequests(authorizeRequests ->
//                        authorizeRequests
//                                .requestMatchers("/oauth2/**").permitAll() // 允许访问 OAuth2 相关资源
//                                .anyRequest().authenticated()
//                )
//                // 使用 OAuth2 登录用户,登录页面将出现第三方授权登录选项
//                .oauth2Login(Customizer.withDefaults())
//                // 使用默认的 OAuth2 客户端配置
//                .oauth2Client(Customizer.withDefaults());
//        return http.build();
//    }

    // 自定义 ClientRegistrationRepository 参考 https://docs.springjava.cn/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-override-boot-autoconfig
    // 通过查询数据库获取客户端注册信息
    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        // TODO 查询数据库，数据表来自 oauth2 client 官方库提供，表名为 oauth2-client-schema.sql
        List<ClientRegistration> clientRegistrations = new ArrayList<>();
        clientRegistrations.add(this.googleClientRegistration());
        return new InMemoryClientRegistrationRepository(clientRegistrations);
    }

    private ClientRegistration googleClientRegistration() {
        return ClientRegistration.withRegistrationId("google")
                .clientId("google-client-id")
                .clientSecret("google-client-secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
                .scope("openid", "profile", "email", "address", "phone")
                .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth")
                .tokenUri("https://www.googleapis.com/oauth2/v4/token")
                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
                .userNameAttributeName(IdTokenClaimNames.SUB)
                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
                .clientName("Google")
                .build();
    }

}

// Spring Security 和 OAuth2 的配置可以分开进行。实际上，在某些情况下，将两者分开配置可以提高代码的可读性和维护性，特别是当你的应用程序需要处理多种认证机制或复杂的授权逻辑时。
// 基础的 SecurityConfig 类来处理通用的安全设置，例如 CSRF 保护、跨域资源共享（CORS）等。
// OAuth2 客户端配置。这包括定义客户端注册信息、登录成功后的处理逻辑等。